var _ = require('underscore')
  , React = require('react')
  , cx = require('classnames')
  , DefaultLoadingElement = require('lib/util/defaultLoadingElement.jsx').default
  , DefaultErrorElement = require('lib/util/defaultErrorElement.jsx').default
  , dispatcher = require('lib/dispatcher')
  , Router = require('react-router')

class TopbarItem extends React.Component {
  toggleChildren(item){
    item.expanded = !item.expanded;
    this.updateChildren(item);
  }

  updateChildren(item) {
    var _this = this;
    if(!item.children){
      let deferred = item.fetchChildren();
      if (deferred) {
        deferred.then(function(){
          _this.forceUpdate();
        },function(){
          _this.forceUpdate();
        },function(){
          _this.forceUpdate();
        });
      } else {
        _this.forceUpdate();
      }
    }else{
      _this.forceUpdate();
    }
  } // updateChildren

  loadChildren(props) {
    var id = props.item.id.toString();
    var path = location.hash.substr(1);
    var exists = _.some(path.split('/'),i=>i===id||decodeURIComponent(i)===id);
    var isLast = path.lastIndexOf(id) + id.length === path.length;
    if (exists && !isLast && props.item.hasChildren) {
      props.item.expanded = true;
      this.updateChildren(props.item);
    }
  } // loadChildren

  componentDidMount() {
    this.loadChildren(this.props);
  } // componentDidMount

  componentWillReceiveProps(nextProps) {
    if (this.props.asyncLoad) {
      this.loadChildren(nextProps);
    }
  } // componentWillReceiveProps

  render() {
    let i = this.props.item;
    return (
      <li>
        <div className={
          cx({
            "handle":true,
            "selected":this.props.isSelected
          })
        } data-tip={i.tip||i.name} data-place="right">
          {
            i.hasChildren?
            (
              <a className="collapse" onClick={this.toggleChildren.bind(this,i)}>
                {i.expanded?'-':'+'}
              </a>
            )
            :null
          }

          <a href={this.props.urlRoot+'#'+i.routeUrl}  onClick={this.props.handleClick}>
            <div className="bar-graph" style={{width:(i.ratio*100)+'%'}}></div>
            <div className="bar-text">
              <i className="iconfont icon-arrow"></i>
              <span className="num">{i.fmtVal}</span>
              <span className="name">{i.name}</span>
            </div>
          </a>
        </div>
        {
          _.isArray(i.traces)?(
            <div className="trace_value">
              慢事务追踪：
              {
                i.traces.length?i.traces.map(function(item,ind) {
                  return <a key={ind} href={this.props.urlRoot+'#'+item.routeUrl} title="点击查看慢事务详情">{item.fmtVal}</a>
                },this):'n/a'
              }
            </div>
          ):null
        }
        {
          i.hasChildren&&i.expanded?
          <Topbar store={i.children} />
          :null
        }

      </li>
    );
  }
}

export default class Topbar extends React.Component{
  constructor(props){
    super(props)
    this.state = {}
    this.handleRoute = this.handleRoute.bind(this)
  }
  componentWillUnmount(){
    window.removeEventListener('hashchange', this.handleRoute);
  }
  componentDidMount(){
    window.addEventListener('hashchange', this.handleRoute);
  }
  componentWillReceiveProps(nextProps){
    this.setSelected(nextProps)
  }
  handleRoute(){
    this.setSelected()
  }
  setSelected(props){
    var path = location.hash.substr(1);
    var originPath = path;
    var props = props|| this.props
      , items
      , hasId = false
    if(props.store.data){
      items = props.store.data
      path=path.split('/').map(function(i) {
         return encodeURIComponent(decodeURIComponent(i));
      }).join('/')
      var item = _(items).findWhere({
        routeUrl:path
      })
      if (!item) {
        item = _(items).findWhere({
          routeUrl:originPath
        });
      }
      if(item){
        hasId = true
        this.setState({
          selectedId:item.id
        })
      }
    }
    if(this.state.selectedId&&!hasId){
      this.setState({
        selectedId:null
      })
    }
  }
  handleClick(item){
    this.setSelected()
  }
  render(){
    if(this.props.store.loading){
      return this.renderLoading(this.props.store.params);
    }else if(this.props.store.error){
      return this.renderError(this.props.store.error)
    }else if(this.props.store.data){
      return this.renderBody(this.props.store.data)
    }else{
      return null
    }
  }
  renderLoading(params){
    return <DefaultLoadingElement params={params}/>
  }
  renderError(){
    return <DefaultErrorElement />
  }
  renderBody(data){
    return (
      <ul className="handle-list" style={ this.props.style }>
      {
        data.map(function(i){
          return (
            <TopbarItem
              key={i.id}
              item={i}
              asyncLoad={ this.props.asyncLoad }
              isSelected={this.state.selectedId===i.id}
              handleClick={this.handleClick.bind(this,i)}
              urlRoot={this.props.urlRoot} />
          )
        },this)
      }
      </ul>
    )
  }
}
Topbar.defaultProps = {
  urlRoot:'',
  style: {},
  asyncLoad: true
}
